#-- coding:UTF-8 -- 
#MSG消息服务器

import os
import time
import socket
import threading
import django
import json

# python使用django数据库，下面两条语句是必须的
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
django.setup()

from myAPI.strToDct import toDict
from myAPI.getServerIP import getServerIP
from djDB_UserInfo_Msg_API_V1 import MsgInfo, add, QuerySetToList, find_all

CMD_SENDMSG = 24 #发送MSG信息
CMD_RECEIVEMSG = 25 # 接收MSG信息

CMD_STARTTALK = 14  #通话呼叫请求
CMD_STOPTALK = 15  #通话呼叫结束请求
CMD_ACCEPTTALK = 16 #同时接收通话

REMOTE_RECEIVE_PORT = 3425 # 手机接收端口3425   
REMOTE_SEND_PORT = 3426 # 手机发送端口3426 

SERVER_IP = getServerIP() #获取本机ip地址 192.168.31.18

class msgServer():  
    def __init__(self):
        self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #消息
        self.udp_socket.bind((SERVER_IP, REMOTE_RECEIVE_PORT)) # 梆定端口3425 
        self.udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        
    def startServer(self):
        try:
            threading.Thread(target=self.receMsg).start()   #发送、接收消息
        except socket.error as msg:
            print ('消息线程错误：%s '%msg)

    def receMsg(self):
        while True:
            print('%s:%s Socket UDP服务器，等待接收消息数据...'%(SERVER_IP, REMOTE_RECEIVE_PORT))
            try:
                rec_msg, addr = self.udp_socket.recvfrom(1024)
                print('接收消息数据: ', rec_msg, addr)          
                rec = rec_msg.decode().strip()
                dct = toDict(rec) 
                dct.update({"successSign":""}) #更新（成功标志）。 手机发送信息时{"successSign":"！"}，如果服务器接收、转发都正常，更新为{"successSign":""}。手机发送信息后，若显示字符！，则表示发送可能不成功。
                rec = json.dumps(dct)
                if dct.get("msgCMD", 0) == CMD_SENDMSG:                               
                    self.udp_socket.sendto(rec.encode(), (dct.get("personIp", ""), REMOTE_SEND_PORT)) #消息转发给好友(联系人)                                      
                    self.saveMsg(dct)
                    if dct.get("mediaName", 0) == "":
                        self.udp_socket.sendto(rec.encode(), addr) #转发自己
                elif dct.get("msgCMD", 0) == CMD_STARTTALK:
                    print("REMOTE_SEND_PORT:", REMOTE_SEND_PORT)
                    myNum = self.udp_socket.sendto(rec.encode(), (dct.get("ip", ""), REMOTE_SEND_PORT))
                    #personNum = self.udp_socket.sendto(rec.encode(), (dct.get("personIp", ""), REMOTE_SEND_PORT)) #消息转发给好友(联系人) 
                elif dct.get("msgCMD", 0) == CMD_STOPTALK:
                    print("CMD_STOPTALK  personIp:", CMD_STOPTALK, dct.get("personIp", ""),  REMOTE_RECEIVE_PORT, addr)
                    myNum = self.udp_socket.sendto(rec.encode(), (dct.get("ip", ""), REMOTE_SEND_PORT)) 
                    #personNum = self.udp_socket.sendto(rec.encode(), (dct.get("personIp", ""), REMOTE_SEND_PORT)) #消息转发给好友(联系人)  
                elif dct.get("msgCMD", 0) == CMD_ACCEPTTALK:
                    print("CMD_ACCEPTTALK personIp:", CMD_ACCEPTTALK, dct.get("personIp", ""))
                    myNum = self.udp_socket.sendto(rec.encode(), (dct.get("ip", ""), REMOTE_SEND_PORT))
                    #personNum = self.udp_socket.sendto(rec.encode(), (dct.get("personIp", ""), REMOTE_SEND_PORT)) #消息转发给好友(联系人) 

            except Exception as ex:
                print ('接收消息数据错误：%s '%ex)
                
    def saveMsg(self, dct):
        #1、如果是语音.amr，取出语音文件名。保存为文件media.txt
        if dct.get("mediaName", ""):
            mediaName = dct.get("mediaName", "") if ".amr" in dct.get("mediaName", "") else ""
            with open("media.txt", "w") as f :
                f.write(mediaName) #保存的文件名macPath + "_" + mediaName
            
        #2、消息保存到服务器MsgInfo数据库
        dct.pop("msgCMD")
        if add(dct, MsgInfo):
            print ('保存到数据库MsgInfo成功：%s '%list(QuerySetToList(find_all(MsgInfo)))[-2:]) #截取倒数第2位到结尾
        else:
            print ('保存到数据库MsgInfo失败')
                
if __name__ == '__main__':
    msg_server = msgServer() #创建新服务器侦听连接
    threading.Thread(target=msg_server.startServer).start()                    
                
                